package com.hddf.project.service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.hibernate.Session;
import org.kommii.mysql_conn_pool.SessionProvider;

import com.hddf.project.base.BaseService;
import com.hddf.project.dao.FirstCategoryDao;
import com.hddf.project.dao.SecondCategoryDao;
import com.hddf.project.dao.ThirdCategoryDao;
import com.hddf.project.impl.FirstCategoryDaoImpl;
import com.hddf.project.impl.SecondCategoryDaoImpl;
import com.hddf.project.impl.ThirdCategoryDaoImpl;
import com.hddf.project.pojos.FirstCategory;
import com.hddf.project.pojos.SecondCategory;
import com.hddf.project.pojos.ThirdCategory;
import com.hddf.project.util.O;
import com.hddf.project.util.Stct;

public class CategoryService extends BaseService {

	private static CategoryService sc = null;
	private static FirstCategoryDao fcd = null;
	private static SecondCategoryDao scd = null;
	private static ThirdCategoryDao tcd = null;
	private static ProjectService ps = null;

	static {
		if (null == sc) {
			sc = new CategoryService();
		}
		if (null == fcd) {
			fcd = new FirstCategoryDaoImpl();
		}
		if (null == scd) {
			scd = new SecondCategoryDaoImpl();
		}
		if (null == tcd) {
			tcd = new ThirdCategoryDaoImpl();
		}
		if (null == ps) {
			ps = ProjectService.getInService();
		}
	}

	public static CategoryService getInService() {
		return sc;
	}

	/**
	 * 添加一级类别
	 * 
	 * @param fc
	 */
	public FirstCategory addFirstCategory(String name, Integer sort, Integer isSort) throws Exception {
		this.sort(sort, 1, isSort, 0, 0);
		FirstCategory fc = new FirstCategory();
		fc.setFirst_category_name(name);
		fc.setSort(sort);
		super.addObject(fc);
		return fc;
	}

	/**
	 * 添加二级类别
	 * 
	 * @param sc
	 */
	public SecondCategory addSecondCategory(String name, Integer sort, Integer f_id, Integer isSort)
			throws Exception {
		this.sort(sort, 2, isSort, 0, f_id);
		SecondCategory sc = new SecondCategory();
		sc.setSecond_category_name(name);
		sc.setSort(sort);
		sc.setFirst_category_id(f_id);
		super.addObject(sc);
		return sc;
	}

	/**
	 * 添加三级类别
	 * 
	 * @param tc
	 */
	public ThirdCategory addThirdCategory(String name, Integer sort, Integer s_id, Integer isSort)
			throws Exception {
		this.sort(sort, 3, isSort, 0, 0);
		ThirdCategory tc = new ThirdCategory();
		tc.setThird_category_name(name);
		tc.setSort(sort);
		tc.setSecond_category_id(s_id);
		super.addObject(tc);
		return tc;
	}

	/**
	 * 修改一级分类
	 * 
	 * @param id
	 * @param name
	 * @param sort
	 */
	public void updateFirstCategory(Integer id, String name, Integer sort, Integer isSort) throws Exception {
		FirstCategory fc = this.getFirstCategory(id);
		this.sort(sort, 1, isSort, fc.getSort(), 0);
		fc.setFirst_category_name(name);
		fc.setSort(sort);
		super.updateObject(fc);
	}

	/**
	 * 修改二级分类
	 * 
	 * @param sc
	 */
	public void updateSecondCategory(Integer id, String name, Integer sort, Integer isSort) throws Exception {
		SecondCategory sc = this.getSecondCategory(id);
		this.sort(sort, 2, isSort, sc.getSort(), sc.getFirst_category_id());
		sc.setSecond_category_name(name);
		sc.setSort(sort);
		super.updateObject(sc);
	}

	/**
	 * 修改三级分类
	 * 
	 * @param tc
	 */
	public void updateThirdCategory(Integer id, String name, Integer sort, Integer isSort) throws Exception {
		ThirdCategory tc = this.getThirdCategory(id);
		this.sort(sort, 3, isSort, tc.getSort(), tc.getSecond_category_id());
		tc.setThird_category_name(name);
		tc.setSort(sort);
		super.updateObject(tc);
	}

	/**
	 * 根据ID获取一级分类
	 * 
	 * @param first_category_id
	 * @return
	 */
	public FirstCategory getFirstCategory(Integer first_category_id) {
		return (FirstCategory) super.getObjectById(first_category_id, FirstCategory.class);
	}

	/**
	 * 根据ID获取二级分类
	 * 
	 * @param first_category_id
	 * @return
	 */
	public SecondCategory getSecondCategory(Integer second_category_id) throws Exception {
		return (SecondCategory) super.getObjectById(second_category_id, SecondCategory.class);
	}

	/**
	 * 根据ID获取三级分类
	 * 
	 * @param first_category_id
	 * @return
	 */
	public ThirdCategory getThirdCategory(Integer third_category_id) throws Exception {
		return (ThirdCategory) super.getObjectById(third_category_id, ThirdCategory.class);
	}

	/**
	 * 获取所有一级分类
	 * 
	 * @return
	 */
	public List<FirstCategory> getAllFirstCategory() {
		Session s = null;
		try {
			List<FirstCategory> list = null;
			s = SessionProvider.getSession();
			list = fcd.getList(s);
			SessionProvider.commitSession(s);
			return list;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据一级类别ID获取二级子分类
	 * 
	 * @param f_id
	 * @return
	 */
	public List<SecondCategory> getSecondCategoryByFirstCategoryId(Integer f_id) {
		Session s = null;
		try {
			List<SecondCategory> scList = null;
			s = SessionProvider.getSession();
			scList = scd.getListByFirstCategory(f_id, s);
			SessionProvider.commitSession(s);
			return scList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据二级ID获取三级子类别
	 * 
	 * @param s_id
	 * @return
	 */
	public List<ThirdCategory> getThirdCategoryBySecondCategoryId(Integer s_id) {
		Session s = null;
		try {
			List<ThirdCategory> scList = null;
			s = SessionProvider.getSession();
			scList = tcd.getListBySecondCategoryId(s_id, s);
			SessionProvider.commitSession(s);
			return scList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取一级分类并获取改分类对应的二级子分类和二级子分类对应的三级子分类
	 * 
	 * @param f_id
	 * @return
	 */
	public FirstCategory getFirstCategoryAndOthers(Integer f_id) {
		FirstCategory fc = this.getFirstCategory(f_id);
		List<SecondCategory> scList = this.getSecondCategoryByFirstCategoryId(f_id);
		if (O.listIsEmpty(scList)) {// 如果二级不为空
			for (int i = 0; i < scList.size(); i++) {// 循环二级分类，查询二级分类的三级子分类
				SecondCategory sc = scList.get(i);
				List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(sc.getSecond_category_id());
				if (O.listIsEmpty(tcList)) {
					sc.setThirdCategories(tcList);// 将存在的三级子分类添加到总集合中
				}
			}
			fc.setSecondCategories(scList);// 将二级集合添加到一级集合中
		}
		return fc;
	}

	/**
	 * 获取所有一级分类，并且获取相对应的二级分类和二级分类对应的三级子分类
	 * 
	 * @return list
	 */
	public List<FirstCategory> getListFirstCategoryAndOthers() {
		List<FirstCategory> list = new ArrayList<FirstCategory>();
		List<FirstCategory> idList = this.getAllFirstCategoryId();
		if (O.listIsEmpty(idList)) {
			for (int i = 0; i < idList.size(); i++) {
				FirstCategory fc = idList.get(i);
				FirstCategory fc_end = this.getFirstCategoryAndOthers(fc.getFirst_category_id());
				list.add(fc_end);
			}
		}
		return list;
	}

	/**
	 * 三级分类未使用则删除，否则不删除
	 * 
	 * @param t_id
	 * @return -1异常、1成功、2已使用
	 */
	public Integer deleteThirdCategoryAndOthers(Integer t_id, Integer isSort) throws Exception {
		int result = ps.getCountByThirdCategory(t_id);
		switch (result) {
		case 0:
			if (isSort == Stct.SORT_IS) {
				ThirdCategory tc = this.getThirdCategory(t_id);
				this.sortDelete(tc.getSort(), 3, tc.getSecond_category_id());
			}
			this.deleteThirdCategory(t_id);
			result = Stct.MESSAGE_SUCCESS;
			break;
		case Stct.ERROR:
			result = Stct.ERROR;
			break;
		default:
			result = Stct.MESSAGE_USED;
			break;
		}
		return result;
	}

	/**
	 * 二级分类未使用则删除，否则不删除
	 * 
	 * @param s_id
	 * @return -1异常、1成功、2已使用
	 */
	public Integer deleteSecondCategoryAndOthers(Integer s_id, Integer isSort) throws Exception {
		List<ThirdCategory> list = this.getThirdCategoryBySecondCategoryId(s_id);
		if (O.listIsEmpty(list)) {
			for (ThirdCategory tc : list) {
				int result = ps.getCountByThirdCategory(tc.getThird_category_id());
				if (0 < result) {
					return Stct.MESSAGE_USED;
				}
			}
			// 二级没有被使用
			for (ThirdCategory tc : list) {
				this.deleteThirdCategory(tc.getThird_category_id());
			}
		}
		// 没有三级分类
		if (isSort == Stct.SORT_IS) {
			SecondCategory sc = this.getSecondCategory(s_id);
			this.sortDelete(sc.getSort(), 2, sc.getFirst_category_id());
		}
		this.deleteSecondCategory(s_id);
		return Stct.MESSAGE_SUCCESS;
	}

	/**
	 * 删除一级分类时判断，是否有二级分类，再断判断是否有三级分类，如果有三级分类，则判断三级分类是否已经使用；如果已使用则无法删除，并提示
	 * 
	 * @param first_category_id
	 * @return -1异常、0未处理、1成功删除、2无法删除，已使用
	 */
	public Integer deleteFirstCategoryAndOthers(Integer f_id, Integer isSort) throws Exception {
		List<SecondCategory> scList = this.getSecondCategoryByFirstCategoryId(f_id);// 根据一级ID查二级子分类
		if (O.listIsEmpty(scList)) {
			for (SecondCategory sc : scList) {
				List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(sc.getSecond_category_id());
				if (O.listIsEmpty(tcList)) {
					for (ThirdCategory tc : tcList) {
						int result = ps.getCountByThirdCategory(tc.getThird_category_id());
						if (result > 0) {
							return Stct.MESSAGE_USED;
						}
					}
				}
			}
			// 都没有被使用则删除
			for (SecondCategory sc : scList) {
				List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(sc.getSecond_category_id());
				if (O.listIsEmpty(tcList)) {
					for (ThirdCategory tc : tcList) {
						this.deleteThirdCategory(tc.getThird_category_id());
					}
				}
				this.deleteSecondCategory(sc.getSecond_category_id());
			}
		}
		// 没有二级分类
		if (isSort == Stct.SORT_IS) {
			FirstCategory fc = this.getFirstCategory(f_id);
			this.sortDelete(fc.getSort(), 1, 0);
		}
		this.deleteFirstCategory(f_id);
		return Stct.MESSAGE_SUCCESS;
	}

	/**
	 * 删除全部类别
	 * 
	 * @return getAllProject
	 */
	public Integer deleteAllCategory() throws Exception {
		int result = ps.getAllProject();
		if (result > 0) {
			return Stct.MESSAGE_USED;
		}
		List<FirstCategory> fcIds = this.getAllFirstCategoryId();
		this.deleteCategories(fcIds, 1);
		return Stct.MESSAGE_SUCCESS;
	}

	/**
	 * 批量删除分类
	 * 
	 * @param ids
	 *            ID字符串
	 * @param type
	 *            1：一级分类；2：二级分类；3：三级分类
	 * @return -1异常、0未处理、1成功删除、2无法删除，已使用
	 */
	public Integer deleteCategories(List<FirstCategory> ids, Integer type) throws Exception {
		int result = 0;
		for (int i = 0; i < ids.size(); i++) {
			FirstCategory fc = ids.get(i);
			switch (type) {
			case 1:
				result = this.deleteFirstCategoryAndOthers(fc.getFirst_category_id(), 1);
				break;
			case 2:
				result = this.deleteSecondCategoryAndOthers(fc.getFirst_category_id(), 1);
				break;
			case 3:
				result = this.deleteThirdCategoryAndOthers(fc.getFirst_category_id(), 1);
				break;
			}
			switch (result) {
			case Stct.ERROR:
				return Stct.ERROR;
			case Stct.MESSAGE_USED:
				return Stct.MESSAGE_USED;
			}
		}
		return Stct.MESSAGE_SUCCESS;
	}

	/**
	 * 排序
	 * 
	 * @param sort
	 *            排序的数字
	 * @param type
	 *            类别：1一级分类，2二级分类，3三级分类
	 * @param isSort
	 *            添加时是否需要排序,2需要排序
	 * @param oldSort
	 *            之前的排序，可为空；如添加时排序则为空
	 * @param parentId
	 *            父类ID，可空
	 */
	private void sort(Integer sort, Integer type, Integer isSort, Integer oldSort, Integer parentId)
			throws Exception {
		if (isSort == Stct.SORT_IS) {
			if (oldSort > sort) {
				this.sortAsc(parentId, type, oldSort, sort);
			} else if (oldSort < sort) {
				this.sortDesc(parentId, type, oldSort, sort);
			}
		}
	}

	/**
	 * 更改排序:将小排序变成大排序
	 * 
	 * @param parentId
	 *            父类ID，可空
	 * @param type
	 *            类别：1一级分类，2二级分类，3三级分类
	 * @param sort
	 *            排序开始数
	 */
	private void sortAsc(Integer parentId, Integer type, Integer oldSort, Integer newSort) throws Exception {
		switch (type) {
		case 1:
			List<FirstCategory> fcList = this.getAllFirstCategory();
			if (O.listIsEmpty(fcList)) {
				for (FirstCategory fc : fcList) {
					if (newSort <= fc.getSort() && fc.getSort() < oldSort) {// 如果之前的排序大于新的排序则加一
						fc.setSort(fc.getSort() + 1);
						super.updateObject(fc);
					}
				}
			}
			break;
		case 2:
			List<SecondCategory> scList = this.getSecondCategoryByFirstCategoryId(parentId);
			if (O.listIsEmpty(scList)) {
				for (SecondCategory sc : scList) {
					if (newSort <= sc.getSort() && sc.getSort() < oldSort) {// 如果之前的排序大于新的排序则加一
						sc.setSort(sc.getSort() + 1);
						super.updateObject(sc);
					}
				}
			}
			break;
		case 3:
			List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(parentId);
			if (O.listIsEmpty(tcList)) {
				for (ThirdCategory tc : tcList) {
					if (newSort <= tc.getSort() && tc.getSort() < oldSort) {// 如果之前的排序大于新的排序则加一
						tc.setSort(tc.getSort() + 1);
						super.updateObject(tc);
					}
				}
			}
			break;
		}
	}

	/**
	 * 更改排序:将大排序变成小排序
	 * 
	 * @param parentId
	 *            父类ID，可空
	 * @param type
	 *            类别：1一级分类，2二级分类，3三级分类
	 * @param sort
	 *            排序开始数
	 */
	private void sortDesc(Integer parentId, Integer type, Integer oldSort, Integer newSort) throws Exception {
		switch (type) {
		case 1:
			List<FirstCategory> fcList = this.getAllFirstCategory();
			if (O.listIsEmpty(fcList)) {
				for (FirstCategory fc : fcList) {
					if (newSort >= fc.getSort() && fc.getSort() > oldSort) {// 如果之前的排序大于新的排序则加一
						fc.setSort(fc.getSort() - 1);
						super.updateObject(fc);
					}
				}
			}
			break;
		case 2:
			List<SecondCategory> scList = this.getSecondCategoryByFirstCategoryId(parentId);
			if (O.listIsEmpty(scList)) {
				for (SecondCategory sc : scList) {
					if (newSort >= sc.getSort() && sc.getSort() > oldSort) {// 如果之前的排序大于新的排序则加一
						sc.setSort(sc.getSort() - 1);
						super.updateObject(sc);
					}
				}
			}
			break;
		case 3:
			List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(parentId);
			if (O.listIsEmpty(tcList)) {
				for (ThirdCategory tc : tcList) {
					if (newSort >= tc.getSort() && tc.getSort() > oldSort) {// 如果之前的排序大于新的排序则加一
						tc.setSort(tc.getSort() - 1);
						super.updateObject(tc);
					}
				}
			}
			break;
		}
	}

	/**
	 * 更改排序:将小排序变成大排序
	 * 
	 * @param parentId
	 *            父类ID，可空
	 * @param type
	 *            类别：1一级分类，2二级分类，3三级分类
	 * @param sort
	 *            排序开始数
	 */
	private void sortDelete(Integer newSort, Integer type, Integer parentId) throws Exception {
		switch (type) {
		case 1:
			List<FirstCategory> fcList = this.getAllFirstCategory();
			if (O.listIsEmpty(fcList)) {
				for (FirstCategory fc : fcList) {
					if (newSort < fc.getSort()) {// 如果之前的排序大于新的排序则加一
						fc.setSort(fc.getSort() - 1);
						super.updateObject(fc);
					}
				}
			}
			break;
		case 2:
			List<SecondCategory> scList = this.getSecondCategoryByFirstCategoryId(parentId);
			if (O.listIsEmpty(scList)) {
				for (SecondCategory sc : scList) {
					if (newSort < sc.getSort()) {// 如果之前的排序大于新的排序则加一
						sc.setSort(sc.getSort() - 1);
						super.updateObject(sc);
					}
				}
			}
			break;
		case 3:
			List<ThirdCategory> tcList = this.getThirdCategoryBySecondCategoryId(parentId);
			if (O.listIsEmpty(tcList)) {
				for (ThirdCategory tc : tcList) {
					if (newSort < tc.getSort()) {// 如果之前的排序大于新的排序则加一
						tc.setSort(tc.getSort() - 1);
						super.updateObject(tc);
					}
				}
			}
			break;
		}
	}

	/**
	 * 删除一级分类
	 * 
	 * @param fc
	 */
	private void deleteFirstCategory(Integer first_category_id) throws Exception {
		super.deleteObject(first_category_id, FirstCategory.class);
	}

	/**
	 * 删除二级分类
	 * 
	 * @param first_category_id
	 */
	private void deleteSecondCategory(Integer second_category_id) throws Exception {
		super.deleteObject(second_category_id, SecondCategory.class);
	}

	/**
	 * 删除三级分类
	 * 
	 * @param first_category_id
	 */
	private void deleteThirdCategory(Integer third_category_id) throws Exception {
		super.deleteObject(third_category_id, ThirdCategory.class);
	}

	/**
	 * 获取所有一级分类ID
	 * 
	 * @return
	 */
	private List<FirstCategory> getAllFirstCategoryId() {
		Session s = null;
		try {
			List<FirstCategory> list = null;
			s = SessionProvider.getSession();
			list = fcd.getAllFirstCategoryId(s);
			SessionProvider.commitSession(s);
			return list;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取所有一级分类
	 * 
	 * @return
	 */
	public List<FirstCategory> getAllFirstCategoryAndCount() {
		try {
			List<FirstCategory> list = this.getAllFirstCategory();
			List<FirstCategory> _list = new LinkedList<FirstCategory>();
			if (O.ckLt(list)) {
				for (int i = 0; i < list.size(); i++) {
					FirstCategory fc = list.get(i);
					int result = ps.getProjectCountByCategoryFirst(fc.getFirst_category_id());
					fc.setCount(result);
					_list.add(fc);
				}
			}
			return _list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据一级类别ID获取小于等于排序数的二级子类别
	 * 
	 * @param first_category_id
	 * @param s
	 * @return
	 */
	public List<SecondCategory> listSecondCategory(int first_category_id, int sort) {
		Session s = null;
		try {
			List<SecondCategory> list = null;
			s = SessionProvider.getSession();
			list = scd.listSecondCategory(first_category_id, sort, s);
			SessionProvider.commitSession(s);
			return list;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取所有一级分类
	 * 
	 * @return
	 */
	public List<SecondCategory> listIndexCategory() {
		try {
			List<SecondCategory> list = this.listSecondCategory(1, 4);
			List<SecondCategory> _list = new LinkedList<SecondCategory>();
			if (O.ckLt(list)) {
				for (int i = 0; i < list.size(); i++) {
					SecondCategory sc = list.get(i);
					int result = ps.getProjectsCountBySecondCategory(sc.getSecond_category_id(), null);
					sc.setCount(result);
					_list.add(sc);
				}
			}
			return _list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}